﻿using System;
using System.IO;

namespace Game.Lib

{
    public struct MicroPacket : Serializable, IComparable
    {
        public const int MAXIMUM_SIZE = 4096;
        public const int HEADER_SIZE = 10;

        public byte[] Data;
        public ushort Length;
        public uint Packet;
        public ushort Section;
        public ushort Count;

        public MicroPacket(byte[] data, uint packet, ushort section, ushort cnt)
        {
            if(data.Length > MAXIMUM_SIZE) throw new ArgumentException("Data must be no more than 4KB.");
            Data = data;
            Length = (ushort)data.Length;
            Packet = packet;
            Section = section;
            Count = cnt;
        }

        public void FromBytes(byte[] data, int pos)
        {

        }

        public byte[] ToBytes()
        {
            int size = Data.Length + 10;
            byte[] ret = new byte[size];
            Buffer.BlockCopy(BitConverter.GetBytes(Packet), 0, ret, 0, 4);
            Buffer.BlockCopy(BitConverter.GetBytes(Section), 0, ret, 4, 2);
            Buffer.BlockCopy(BitConverter.GetBytes(Count), 0, ret, 6, 2);
            Buffer.BlockCopy(BitConverter.GetBytes(Length), 0, ret, 8, 2);
            Buffer.BlockCopy(Data, 0, ret, 10, Data.Length);
            return ret;
        }

        public void Serialize(Stream s)
        {
            s.Write(BitConverter.GetBytes(Packet), 0, 4);
            s.Write(BitConverter.GetBytes(Section), 0, 2);
            s.Write(BitConverter.GetBytes(Count), 0, 2);
            s.Write(BitConverter.GetBytes(Length), 0, 2);
            s.Write(Data, 0, Data.Length);
        }

        public void Deserialize(Stream s)
        {
            byte[] buf = new byte[4];

            int temp = s.Read(buf, 0, 4);
            if(temp != 4) throw new EndOfStreamException("Stream cut out during packet");
            Packet = BitConverter.ToUInt32(buf, 0);

            temp = s.Read(buf, 0, 2);
            if(temp != 2) throw new EndOfStreamException("Stream cut out during packet");
            Section = BitConverter.ToUInt16(buf, 0);

            temp = s.Read(buf, 0, 2);
            if(temp != 2) throw new EndOfStreamException("Stream cut out during packet");
            Count = BitConverter.ToUInt16(buf, 0);

            temp = s.Read(buf, 0, 2);
            if(temp != 2) throw new EndOfStreamException("Stream cut out during packet");
            Length = BitConverter.ToUInt16(buf, 0);

            Data = new byte[Length];
            temp = s.Read(Data, 0, Length);
            if(temp != Length) throw new EndOfStreamException("Stream cut out during packet");
        }

        public int CompareTo(object obj)
        {
            if(obj is MicroPacket)
            {
                return this.Section - ((MicroPacket)obj).Section;
            }
            else
            {
                return 1;
            }
        }
    }
}
